/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "stdafx.h"
#include "SoundSource.h"
#include <alc.h>
#include <al\alut.h>

SoundSource::SoundSource(void)
{
	m_destroy = false;
	m_ready   = false;

	m_playing = false;
	m_stopped = true;
	m_paused  = false;
	m_looping = false;

	m_volume  = 0.0f;

    m_pos.ZeroOut();
	m_vel.ZeroOut();

	m_lpos.ZeroOut();
	m_lvel.ZeroOut();
}

/**
================
Load the sound file
Will move this into Resource
================
*/
int SoundSource::Load(const std::string &sound_file )
{

	// Load the WAV file into memory
	buffer.SetBuffer ( alutCreateBufferFromFile ( sound_file.c_str() ) );

	// Check for errors
	if (alGetError() != AL_NO_ERROR)
        return 1;

	// Bind buffer with a source.
    alGenSources(1, &source);
    
    if (alGetError() != AL_NO_ERROR)
        return 1;

	// load the buffer
	alSourcei (source, AL_BUFFER,   buffer.GetBuffer());
    alSourcei( source, AL_SOURCE_RELATIVE, true );
    alSourcef( source, AL_MIN_GAIN, 0.3f );
    alSourcef( source, AL_CONE_OUTER_GAIN, 1.0f );
    float d[3]; 
    d[0]=0;d[1]=0;d[2]=1;
    alSourcefv( source, AL_DIRECTION, d );
    alSourcef (source, AL_PITCH,    1.0f     );
    alSourcef (source, AL_GAIN,     m_volume );
	float f[3];
	f[0] = m_pos.x; f[1] = m_pos.y; f[2] = 0;
    alSourcefv(source, AL_POSITION, f);

	f[0] = m_vel.x; f[1] = m_vel.y; f[2] = 0;
    alSourcefv(source, AL_VELOCITY, f);
	
	// set the ready flag
	m_ready = true;
    
    // TODO - FIND LOADING ERROR CODE - AND MAKE OGG DECODER
	// Do an error check and return.
    return (alGetError() != AL_NO_ERROR);
}

/** Test to see if this source is ready for playing */
bool SoundSource::IsReady() 
{ 
	return m_ready && (alGetError() == AL_NO_ERROR); 
}

/** Update the location of the sound */
void SoundSource::Update(long deltaTime)
{
	float f[3];
	f[0] = m_pos.x; f[1] = m_pos.y; f[2] = 0;
    alSourcefv(source, AL_POSITION, f);

	f[0] = m_vel.x; f[1] = m_vel.y; f[2] = 0;
    alSourcefv(source, AL_VELOCITY, f);

}

/** Destroy the sound */
void SoundSource::Destroy()
{
	Stop();
	// delete buffers and sources
	buffer.Delete();
	alDeleteSources( 1, &source);

	m_destroy = true;
}


/**
 * Plays the sound, loops if necessary
 */
void SoundSource::Play(bool loop)
{
    int i = 0;
    alGetSourcei( source, AL_SOURCE_STATE, &i );
    if ( i == AL_PLAYING )
        return;

	m_looping = loop;
	m_stopped = false;
	m_paused  = false;
	m_playing = true;

	// play the sound
	alSourcei (source, AL_LOOPING,  loop ? AL_TRUE : AL_FALSE );
	alSourcePlay(source);

}


/** Loop the sound */
void SoundSource::Loop()
{
    if ( m_playing )
        return;
    Play(true);
}

/** Stops the sound */
void SoundSource::Stop()
{
	m_stopped = true;
	m_paused  = false;
	m_playing = false;

	// stop the sound
	alSourceStop(source);

}

/** Pauses the sound */
void SoundSource::Pause()
{
	m_stopped = false;
	m_paused  = true;
	m_playing = false;

	// pause the sound
	alSourcePause(source);
	
}

/** Resumes the sound */
void SoundSource::Resume()
{
	Play(m_looping);
}

/** Sets the volume of the sound */
void SoundSource::Volume( float v )
{
    m_volume = v;
	// Not sure what we should do with Pitch just yet
	// alSourcef(Source, AL_PITCH, 1.0f);
    alSourcef(source, AL_GAIN,  v);

}

/** Get Size in bytes */
int  SoundSource::GetSizeInBytes() const
{
    int size = 0;
    alGetBufferi( source, AL_SIZE, &size );
    return size;
}
/** Get Frequency */
float  SoundSource::GetFrequency() const
{
    float freq = 0.0f;
    alGetBufferf( source, AL_FREQUENCY, &freq );
    return freq;
}

SoundSource::~SoundSource(void)
{
	Destroy();
}
